package cn.jx.asc.service.impl;

import cn.jx.asc.common.constant.Contants;
import cn.jx.asc.common.enums.Sex;
import cn.jx.asc.common.enums.UserStatu;
import cn.jx.asc.common.utils.MD5Utils;
import cn.jx.asc.dao.mapper.RoleMapper;
import cn.jx.asc.dao.mapper.UserMapper;
import cn.jx.asc.pojo.bo.RegistUserBO;
import cn.jx.asc.pojo.bo.UserInfoBO;
import cn.jx.asc.pojo.entity.User;
import cn.jx.asc.pojo.vo.RoleVO;
import cn.jx.asc.pojo.vo.UserInfoVO;
import cn.jx.asc.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author lhg
 */

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Transactional(propagation = Propagation.SUPPORTS ,rollbackFor=Exception.class)
    @Override
    public boolean queryUsernameIsExist(String username) {
        HashMap<String,Object> map = new HashMap<>(1);
        map.put("username",username);
        List<User> users = userMapper.selectByMap(map);
        return !users.isEmpty();
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public boolean queryUserIdIsExist(String userId) {
        HashMap<String,Object> map = new HashMap<>(1);
        map.put("id",userId);
        List<User> users = userMapper.selectByMap(map);
        return !users.isEmpty();
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    @Override
    public User createUser(RegistUserBO registUserBO) {
        String userId = registUserBO.getUserId();
        User user = new User();
        user.setId(userId);
        user.setUsername(registUserBO.getUsername());

        try {
            user.setPassword(MD5Utils.getMD5Str(registUserBO.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        user.setUsername(registUserBO.getUsername());
        user.setRealname(registUserBO.getRealname());
        user.setProfilePhoto(Contants.USER_FACE);
        user.setStatu(UserStatu.REGISTER.type);
        user.setSex(Sex.secret.type);
        user.setAge(20);
        userMapper.insert(user);
        return user;
    }

    @Override
    public User addUser(RegistUserBO registUserBO) {
        String userId = registUserBO.getUserId();
        User user = new User();
        user.setId(userId);
        user.setUsername(registUserBO.getUsername());
        try {
            user.setPassword(MD5Utils.getMD5Str(registUserBO.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        user.setUsername(registUserBO.getUsername());
        user.setRealname(registUserBO.getRealname());
        user.setProfilePhoto(Contants.USER_FACE);
        user.setStatu(UserStatu.NORMAL.type);
        user.setSex(Sex.secret.type);
        user.setAge(20);
        userMapper.insert(user);
        return user;
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public User queryUserForLogin(String username, String password) {
        HashMap<String,Object> map = new HashMap<>(5);
        map.put("username",username);
        map.put("password",password);
        List<User> users = userMapper.selectByMap(map);
        if (users.isEmpty()){
            return null;
        }
        return users.get(0);
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public UserInfoBO queryAllUsers(long current, long size) {
        final UserInfoBO userInfoBO = new UserInfoBO();
        List<UserInfoVO>  userInfos= new ArrayList<>();
        Page<User> page = new Page<>(current,size);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("statu",0);
        Page<User> userPage = userMapper.selectPage(page, queryWrapper);
        getUserInfoVos(userInfos,userPage.getRecords());
        userInfoBO.setCurrent(userPage.getCurrent());
        userInfoBO.setSize(userPage.getSize());
        userInfoBO.setTotal(userPage.getTotal());
        userInfoBO.setList(userInfos);

        return userInfoBO;
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    @Override
    public Boolean modifyPasswordById(String userId ,String password) {
        User user = userMapper.selectById(userId);
        if (user != null){
            user.setPassword(password);
            user.setUpdatedTime( null );
            final int i = userMapper.updateById(user);
            return i == 1;
        }
        return false;
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public Boolean modifyUserStatusById(String userId, Integer userStatus) {
        User user = userMapper.selectById(userId);
        if (user != null){
            user.setStatu(userStatus);
            user.setUpdatedTime( null );
            final int i = userMapper.updateById(user);
            return i == 1;
        }
        return false;
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
    @Override
    public Boolean deleteUserById(String userId) {
        int i = userMapper.deleteById(userId);
        return i == 1;
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public User queryUserById(String userId) {
        return userMapper.selectById(userId);
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public User queryUserByName(String username) {

        HashMap<String,Object> map = new HashMap<>(5);
        map.put("username",username);
        List<User> users = userMapper.selectByMap(map);
        if (users.isEmpty()){
            return null;
        }
        return users.get(0);
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor=Exception.class)
    @Override
    public UserInfoBO queryRegisterUser(long current, long size) {
        final UserInfoBO userInfoBO = new UserInfoBO();
        List<UserInfoVO>  userInfos= new ArrayList<>();
        Page<User> page = new Page<>(current,size);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("statu",0);
        Page<User> userPage = userMapper.selectPage(page, queryWrapper);
        getUserInfoVos(userInfos,userPage.getRecords());
        userInfoBO.setCurrent(userPage.getCurrent());
        userInfoBO.setSize(userPage.getSize());
        userInfoBO.setTotal(userPage.getTotal());
        userInfoBO.setList(userInfos);

        return userInfoBO;
    }

    static void setUserInfoVo(UserInfoVO userInfoVO, User user) {
        userInfoVO.setId(user.getId());
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setRealname(user.getRealname());
        userInfoVO.setEmail(user.getEmail());
        userInfoVO.setTelephone(user.getTelephone());
        String userStatus ;

        if (user.getStatu().equals(Contants.REGISTER)){

            userStatus = UserStatu.REGISTER.value;

        } else if ( user.getStatu().equals( Contants.NORMAL ) ){

            userStatus = UserStatu.NORMAL.value;
        }else if (user.getStatu().equals( Contants.DEACTIVATE ) ){
        userStatus = UserStatu.DEACTIVATE.value;
        }else {
            userStatus = "账号异常";
        }
        userInfoVO.setStatus( userStatus );
    }

    private List<UserInfoVO> getUserInfoVos(List<UserInfoVO> userInfos, List<User> users) {
        if ( users != null){
            for (User user : users){
                if (user != null){
                    UserInfoVO infoVO = new UserInfoVO();
                    String userId = user.getId();
                    setUserInfoVo( infoVO , user );
                    RoleVO roleVO = roleMapper.queryRoleByUserId( userId );
                    if ( roleVO != null ){
                        infoVO.setRoleName(roleVO.getName());
                    }
                    userInfos.add(infoVO);
                }

            }
        }
        return userInfos;
    }
}
